//AUTHOR:  Aaron Kaufman
#include <stdlib.h>
#define MAX_SIZE 300
#include "ProcessScheduler.h"


ProcessList initializeProcessList(ProcessScheduler* process_scheduler){
	ProcessList* list = (ProcessList*) malloc(sizeof(ProcessList));
	list->size = 0;
	return *list;
}

void addProcessToList(Process process, ProcessScheduler* this){
	ProcessScheduler process_scheduler = *this;
	process_scheduler.process_list.processes[process_scheduler.process_list.size] = process;
	process_scheduler.process_list.size++;
}


void buildNewSchedule(ScheduleType type, ProcessScheduler* this){
	int i = 0;
	int j = 0;
	Scheduler* schedule = &(this->scheduler);
	ProcessList* list  = &(this->process_list);
	schedule->current_process = 0;
	schedule->type = type;
	schedule->size=  0;
	for (i = 0; i < list->size; i++){
		//Add the process to the scheduler a number of times equal to its priority
		for (j = 0; j < list->processes[i].priority; j++){
			schedule->processes[schedule->size] = &(list->processes[i]);
			schedule->size++;
		}
	}
}
/*
 * Requires buildNewSchedule to have been run beforehand.
 */
Process* getNextProcess(ProcessScheduler* this){
	ScheduleType type = (this->scheduler.type);
	Scheduler* schedule = &(this->scheduler);
	int current_process = schedule->current_process;
	if (type == ROUND_ROBIN || type == PRIORITY){
		schedule->current_process++;
		schedule->current_process = schedule->current_process % schedule->size;
		return (schedule->processes[current_process]);
	}
	else if (type == LOTTERY){
		int r = rand() % schedule->size;
		return (schedule->processes[r]);
	}
	else{//Shouldn't ever be reached
		return (schedule->processes[current_process]);
	}
}

/*
 * Like getNextProcess, but is guaranteed to be a DIFFERENT process.
 */
Process* getNewProcess(Process* current, ProcessScheduler* this){
	Process* next = current;
	while(current==next){
		//printf("Moving to next process in list.");
		//printf("Current process : %d\n", this->scheduler.current_process);
		next = getNextProcess(this);
	}
	return next;
}

